#pragma once
#include <FastDelegate.h>
#include <list>
#include <algorithm>
namespace fastevent
{
using namespace fastdelegate;
using namespace std;


class FastEvent0
{
private:
	typedef FastDelegate0<> handler_t;
	typedef list<handler_t> handlers_t;
	typedef handlers_t::iterator iterator;
	typedef handlers_t::const_iterator const_iterator;
	handlers_t handlers;
public:
	void AddHandler(const handler_t& handler)
	{
		handlers.push_back(handler);
	}
	void RemoveHandler(const handler_t& handler)
	{
		handlers.remove(handler);
	}
	bool IsEmpty()
	{
		return handlers.empty();
	}
	void operator()()
	{
		for(const_iterator it = handlers.begin(); it != handlers.end(); ++it)
		{
			(*it)();
		}
	}
};

template <typename Param1>
class FastEvent1
{
private:
	typedef FastDelegate1<Param1> handler_t;
	typedef list<handler_t> handlers_t;
	typedef typename handlers_t::iterator iterator;
	typedef typename handlers_t::const_iterator const_iterator;
	handlers_t handlers;
public:
	void AddHandler(const handler_t& handler)
	{
		handlers.push_back(handler);
	}
	void RemoveHandler(const handler_t& handler)
	{
		handlers.remove(handler);
	}
	bool IsEmpty()
	{
		return handlers.empty();
	}
	void operator()(Param1 p1)
	{
		for(const_iterator it = handlers.begin(); it != handlers.end(); ++it)
		{
			(*it)( p1);
		}
	}
};
template <typename Param1, typename Param2>
class FastEvent2
{
private:
	typedef FastDelegate2<Param1, Param2> handler_t;
	typedef list<handler_t> handlers_t;
	typedef typename handlers_t::iterator iterator;
	typedef typename handlers_t::const_iterator const_iterator;
	handlers_t handlers;
public:
	void AddHandler(const handler_t& handler)
	{
		handlers.push_back(handler);
	}
	void RemoveHandler(const handler_t& handler)
	{
		handlers.remove(handler);
	}
	bool IsEmpty()
	{
		return handlers.empty();
	}
	void operator()(Param1 p1, Param2 p2)
	{
		for(const_iterator it = handlers.begin(); it != handlers.end(); ++it)
		{
			(*it)( p1,  p2);
		}
	}
};
template <typename Param1, typename Param2, typename Param3>
class FastEvent3
{
private:
	typedef FastDelegate3<Param1, Param2, Param3> handler_t;
	typedef list<handler_t> handlers_t;
	typedef typename handlers_t::iterator iterator;
	typedef typename handlers_t::const_iterator const_iterator;
	handlers_t handlers;
public:
	void AddHandler(const handler_t& handler)
	{
		handlers.push_back(handler);
	}
	void RemoveHandler(const handler_t& handler)
	{
		handlers.remove(handler);
	}
	bool IsEmpty()
	{
		return handlers.empty();
	}
	void operator()(Param1 p1, Param2 p2, Param3 p3)
	{
		for(const_iterator it = handlers.begin(); it != handlers.end(); ++it)
		{
			(*it)( p1,  p2,  p3);
		}
	}
};
template <typename Param1, typename Param2, typename Param3, typename Param4>
class FastEvent4
{
private:
	typedef FastDelegate4<Param1, Param2, Param3, Param4> handler_t;
	typedef list<handler_t> handlers_t;
	typedef typename handlers_t::iterator iterator;
	typedef typename handlers_t::const_iterator const_iterator;
	handlers_t handlers;
public:
	void AddHandler(const handler_t& handler)
	{
		handlers.push_back(handler);
	}
	void RemoveHandler(const handler_t& handler)
	{
		handlers.remove(handler);
	}
	bool IsEmpty()
	{
		return handlers.empty();
	}
	void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4)
	{
		for(const_iterator it = handlers.begin(); it != handlers.end(); ++it)
		{
			(*it)( p1,  p2,  p3,  p4);
		}
	}
};
template <typename Param1, typename Param2, typename Param3, typename Param4, typename Param5>
class FastEvent5
{
private:
	typedef FastDelegate5<Param1, Param2, Param3, Param4, Param5> handler_t;
	typedef list<handler_t> handlers_t;
	typedef typename handlers_t::iterator iterator;
	typedef typename handlers_t::const_iterator const_iterator;
	handlers_t handlers;
public:
	void AddHandler(const handler_t& handler)
	{
		handlers.push_back(handler);
	}
	void RemoveHandler(const handler_t& handler)
	{
		handlers.remove(handler);
	}
	bool IsEmpty()
	{
		return handlers.empty();
	}
	void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5)
	{
		for(const_iterator it = handlers.begin(); it != handlers.end(); ++it)
		{
			(*it)( p1,  p2,  p3,  p4,  p5);
		}
	}
};
template <typename Param1, typename Param2, typename Param3, typename Param4, typename Param5, typename Param6>
class FastEvent6
{
private:
	typedef FastDelegate6<Param1, Param2, Param3, Param4, Param5, Param6> handler_t;
	typedef list<handler_t> handlers_t;
	typedef typename handlers_t::iterator iterator;
	typedef typename handlers_t::const_iterator const_iterator;
	handlers_t handlers;
public:
	void AddHandler(const handler_t& handler)
	{
		handlers.push_back(handler);
	}
	void RemoveHandler(const handler_t& handler)
	{
		handlers.remove(handler);
	}
	bool IsEmpty()
	{
		return handlers.empty();
	}
	void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6)
	{
		for(const_iterator it = handlers.begin(); it != handlers.end(); ++it)
		{
			(*it)( p1,  p2,  p3,  p4,  p5,  p6);
		}
	}
};
template <typename Param1, typename Param2, typename Param3, typename Param4, typename Param5, typename Param6, typename Param7>
class FastEvent7
{
private:
	typedef FastDelegate7<Param1, Param2, Param3, Param4, Param5, Param6, Param7> handler_t;
	typedef list<handler_t> handlers_t;
	typedef typename handlers_t::iterator iterator;
	typedef typename handlers_t::const_iterator const_iterator;
	handlers_t handlers;
public:
	void AddHandler(const handler_t& handler)
	{
		handlers.push_back(handler);
	}
	void RemoveHandler(const handler_t& handler)
	{
		handlers.remove(handler);
	}
	bool IsEmpty()
	{
		return handlers.empty();
	}
	void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7)
	{
		for(const_iterator it = handlers.begin(); it != handlers.end(); ++it)
		{
			(*it)( p1,  p2,  p3,  p4,  p5,  p6,  p7);
		}
	}
};
template <typename Param1, typename Param2, typename Param3, typename Param4, typename Param5, typename Param6, typename Param7, typename Param8>
class FastEvent8
{
private:
	typedef FastDelegate8<Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8> handler_t;
	typedef list<handler_t> handlers_t;
	typedef typename handlers_t::iterator iterator;
	typedef typename handlers_t::const_iterator const_iterator;
	handlers_t handlers;
public:
	void AddHandler(const handler_t& handler)
	{
		handlers.push_back(handler);
	}
	void RemoveHandler(const handler_t& handler)
	{
		handlers.remove(handler);
	}
	bool IsEmpty()
	{
		return handlers.empty();
	}
	void operator()(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8)
	{
		for(const_iterator it = handlers.begin(); it != handlers.end(); ++it)
		{
			(*it)( p1,  p2,  p3,  p4,  p5,  p6,  p7,  p8);
		}
	}
};
}

